package com.inlycat.web.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.inlycat.entity.User;
import com.inlycat.entity.UserInfo;
import com.inlycat.service.UserService;
import com.inlycat.utils.Constant;
import com.inlycat.utils.SMSUtil;
import com.inlycat.utils.StrUtils;
import com.inlycat.utils.redis.RedisClientTemplate;

/**
 * @author jarvan4dev@163.com
 * @since 2015年8月21日上午10:58:18
 * @category 用户访问接口
 **/
@Controller
@RequestMapping(value = "/user")
public class UserController {

	private static final Logger logger = LoggerFactory
			.getLogger(UserController.class);

	@Resource
	private UserService userService;

	@Resource
	private RedisClientTemplate redisClient;

	@RequestMapping(value = "/login", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> login(@Valid User user, BindingResult bResult,
			HttpServletResponse response,HttpServletRequest request) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		if (bResult.hasErrors()) {
			resultMap.put("code", 0);
			List<String> messages = new LinkedList<String>();
			for (FieldError error : bResult.getFieldErrors()) {
				messages.add(error.getDefaultMessage());
			}
			resultMap.put("message", messages);
			logger.info("message", messages);
			return resultMap;
		}
		Map<String, Object> userDetail = userService.login(user,request);
		if (userDetail == null || userDetail.isEmpty()) {// 表明没有数据
			resultMap.put("code", 0);
			resultMap.put("message", "用户名或者密码错误");
			logger.info("message", "用户名或者密码错误");
			return resultMap;
		}

		/**
		 * 将UUID作为键 userID为值存入redis
		 */
		String token_value = UUID.randomUUID().toString();
		String token_key = ((UserInfo) userDetail.get("userInfo")).getUserId()
				+ "";
		redisClient.set(token_key, token_value);
		/**
		 * 设置token过期时间
		 */
		redisClient.expire(token_key, Constant.TOKEN_EXPIRE_TIME);
		/**
		 * 把token放到header中
		 */
		response.setHeader("token", token_value);
		
		resultMap.put("code", 1);
		resultMap.put("message", "登录成功");
		resultMap.put("data", userDetail);
		logger.info("message", "登录成功");
		logger.info("userInfo", userDetail);
		return resultMap;
	}

	@RequestMapping(value = "/register", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> register(String verify, @Valid User user,
			BindingResult bResult, HttpServletResponse response,
			HttpSession session) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		if (verify == null || "".equals(verify)) {
			resultMap.put("code", 0);
			resultMap.put("message", "请输入短信验证码");
			return resultMap;
		}
		if (bResult.hasErrors()) {
			resultMap.put("code", 0);
			Map<String, Object> messageMap = new HashMap<String, Object>();
			for (FieldError error : bResult.getFieldErrors()) {
				messageMap.put(error.getField().intern(),
						error.getDefaultMessage());
			}
			resultMap.put("message", messageMap);
			logger.info("message", messageMap);
			return resultMap;
		}
		String codeInSession = redisClient.get(user.getUsername());

		if (codeInSession == null || "".equals(codeInSession)) {
			resultMap.put("code", 0);
			resultMap.put("message", "请重新获取验证码");
			return resultMap;
		}
		if (!codeInSession.equals(verify)) {
			resultMap.put("code", 0);
			resultMap.put("message", "验证码不正确");
			return resultMap;
		}
		Map<String, Object> userDetail = userService.register(user);
		if (userDetail != null) {
			/**
			 * 注册成功，移除验证码
			 */
			redisClient.del(user.getUsername());
			/**
			 * 将UUID作为键值存入redis
			 */
			String token_value = UUID.randomUUID().toString();
			redisClient.set(user.getId() + "", token_value);
			/**
			 * 设置token过期时间
			 */
			redisClient.expire(user.getId() + "", Constant.TOKEN_EXPIRE_TIME);
			/**
			 * 把token放到header中
			 */
			response.setHeader("token", token_value);

			resultMap.put("code", 1);
			resultMap.put("message", "注册成功");
			resultMap.put("data", userDetail);
			logger.info("message", "注册成功");
		}
		return resultMap;
	}

	@RequestMapping(value = "/changePassword", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> changePassword(String username, String password,
			String rePassword) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		if (!password.equals(rePassword)) {
			resultMap.put("code", 0);
			resultMap.put("message", "两次密码不一致");
			logger.info("message", "两次密码不一致");
			return resultMap;
		}
		
		boolean result = userService.usernameExist(username);
		if(result==false){
			resultMap.put("code", 0);
			resultMap.put("message", "用户名不存在");
			logger.info("message", "用户名不存在");
			return resultMap;
		}
		
		result = userService.changePassword(username, password);
		if (result) {
			resultMap.put("code", 1);
			resultMap.put("message", "密码修改成功");
			logger.info("message", "两次密码不一致");
			return resultMap;
		}
		resultMap.put("code", 0);
		resultMap.put("message", "未知原因密码修改失败");
		return resultMap;
	}

	/**
	 * 获取校验码
	 * @param user
	 * @param bResult
	 * @param request
	 * @param need 用于区分请求验证码是来自于修改密码还是注册
	 * @return
	 */
	@RequestMapping(value = "/verify", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> verify(@Valid User user, BindingResult bResult,
			HttpServletRequest request,boolean need) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		if (bResult.hasErrors()) {
			resultMap.put("code", 0);
			resultMap.put("message", "请输入正确的手机号码");
			return resultMap;
		}
		
		/**
		 * 无论是注册还是修改密码都需要判断当前手机是否已经被注册
		 */
		boolean result = userService.usernameExist(user.getUsername());
		
		if(need){//表示注册
			if (result) {
				resultMap.put("code", 0);
				resultMap.put("message", "该手机号已被注册");
				return resultMap;
			}
		}else{//表示修改密码
			if(result==false){
				resultMap.put("code", 0);
				resultMap.put("message", "该手机号码尚未注册");
				return resultMap;
			}
		}
		int code = StrUtils.getSMSCode();

		redisClient.set(user.getUsername(), code + "");
		redisClient.expire(user.getUsername(), 1800);

		ObjectNode obj = null;
		try {
			obj = SMSUtil.sendSMS(user.getUsername(), code);
			logger.info(obj.get("reason").asText());
		} catch (IOException e) {
			e.printStackTrace();
		}
		resultMap.put("code", 1);
		resultMap.put("message", obj.get("reason").asText());
		return resultMap;
	}

	@RequestMapping(value = "/verifyCode", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> verifyCode(String username, String verify) {
		Map<String, Object> resultMap = new HashMap<String, Object>();

		if (username == null) {
			resultMap.put("code", 0);
			resultMap.put("message", "请输入手机号码");
			return resultMap;
		}

		if (verify == null) {
			resultMap.put("code", 0);
			resultMap.put("message", "请输入短信校验码");
			return resultMap;
		}

		String code = redisClient.get(username);
		if (code == null) {
			resultMap.put("code", 0);
			resultMap.put("message", "短语验证码过期");
			return resultMap;
		}

		if (!code.equals(verify)) {
			resultMap.put("code", 0);
			resultMap.put("message", "短语验证码不正确");
			return resultMap;
		}

		/**
		 * 校验成功后删除校验码
		 */
		redisClient.del(username);

		resultMap.put("code", 1);
		resultMap.put("message", "success");
		return resultMap;
	}

}
